home *** CD-ROM | disk | FTP | other *** search
/ Day Cry / Day Cry CD.bin / oh_towns / taropyon / splib / splib.lzh / PRG / LHX / EXTRACT.C < prev    next >
C/C++ Source or Header  |  1992-12-08  |  7KB  |  340 lines

  1. /***********************************************************
  2.         extract.c -- extract file from archive
  3. ***********************************************************/
  4. #include    "lh386.h"
  5.  
  6. #include    <stdio.h>
  7. #include    <string.h>
  8. #include    <stdlib.h>
  9. #include    <io.h>
  10. #include    <dos.h>
  11. #include    <direct.h>
  12. #include    "lh.h"
  13. #include    "intrface.h"
  14. #include    "errmes.h"
  15.  
  16. #include    <fslib.h>
  17.  
  18. #ifdef    __HIGHC__
  19. #    pragma    On(Align_labels);
  20. #endif
  21.  
  22. /* #define        EX_DEBUG         */
  23.  
  24. extern boolean verify_mode;
  25.  
  26. static char methods[10][5] =
  27. {
  28.     "-lh0-", "-lh1-", "-lh2-", "-lh3-", "-lh4-",
  29.     "-lh5-", "-lzs-", "-lz5-", "-lz4-", "\0\0\0\0\0"
  30. };
  31.  
  32. static void skipdisp(char *mes)
  33. {
  34.     LHX_fprintf(stderr, "Skipped %-12s : %s\n", hpb.filename, mes);
  35. }
  36.  
  37. /*******************************
  38.         test the file name which
  39.         should be melted
  40. *******************************/
  41. static char tstdir(char *name)
  42. {
  43.     char       *p, *q, yn;
  44.     int         absent;
  45.     struct find_t srchbuf;
  46.  
  47.     p = name;
  48.     if (*p && p[1] == ':')        /* skip a drive name */
  49.         p += 2;
  50.     if (*p == DELIM)            /* skip a root mark('\') */
  51.         p++;
  52.     yn = flg_m ? 'Y' : 'N';
  53.     q = p;
  54.     while ((p = strchr(p, DELIM)) != NULL)
  55.     {                            /* skip to next '\' */
  56.         if (*q != '.')
  57.         {
  58.             *p = '\0';
  59.             absent = _dos_findfirst(name, 0x17, &srchbuf);
  60.             if (absent)
  61.             {
  62.                 if (yn == 'N')
  63.                 {
  64.                     *p = DELIM;
  65.                     LHX_fprintf(stderr, "'%s' : %s", name, MKDIR);
  66.                     *p = '\0';
  67.                     yn = getyn();
  68.                 }
  69.                 if (yn == 'N')
  70.                 {
  71.                     return 'S';
  72.                 } else
  73.                 {
  74.                     if (makedir(name))
  75.                     {            /* make directory */
  76.                         error(MKDIRERR, name);
  77.                     }
  78.                 }
  79.             } else
  80.             {
  81.                 if ((srchbuf.attrib & 0x10) == 0)
  82.                 {
  83.                     error(MKDIRERR, name);        /* if the name isn't
  84.                                                  * directory */
  85.                 }
  86.             }
  87.             *p = DELIM;
  88.         }
  89.         q = ++p;
  90.     }
  91.     if (!_dos_findfirst(name, 0x17, &srchbuf))
  92.     {
  93.         /* already exists */
  94.         if (flg_c == 0 &&
  95.             dos2unix((struct ftime *) & srchbuf.wr_time) >= hpb.utc)
  96.             yn = 'S';
  97.         switch (flg_m)
  98.         {
  99.             case 0:
  100.                 if (yn != 'S')
  101.                 {
  102.                     LHX_fprintf(stderr, "'%s' %s", name, OVERWT);
  103.                     yn = (getyn() == 'Y') ? 'O' : 'S';
  104.                     break;
  105.                 }
  106.             case 1:
  107.                 if (yn == 'S')
  108.                 {
  109.                     skipdisp(NEWFILE);
  110.                     break;
  111.                 }
  112.                 yn = 'O';
  113.                 break;
  114.             case 2:
  115.                 yn = 'R';
  116.                 break;
  117.         }
  118.         if (yn != 'O')
  119.         {
  120.             return yn;
  121.         }
  122.         if (srchbuf.attrib & 0x01 &&
  123.             srchbuf.attrib != hpb.attr && flg_a)
  124.         {
  125.             /* if the file is read-only, */
  126.             /* attributes must match */
  127.             skipdisp(RDONLY);
  128.             return 'S';
  129.         }
  130.         if (srchbuf.attrib & 0x10)
  131.         {
  132.             skipdisp(SAMEDIR);
  133.             return 'S';
  134.         }
  135.         if (srchbuf.attrib & 0x07)
  136.             _dos_setfileattr(name, 0x20);        /* reset attributes */
  137.     }
  138.     return 'O';
  139. }
  140.  
  141. static int    rename_ext(char *name)
  142. {
  143.     int         i;
  144.     char       *p, *q;
  145.     struct find_t srchbuf;
  146.  
  147.     p = strrchr(name, '.');
  148.     q = strrchr(name, DELIM);
  149.     if (p <= q)
  150.         p = name + strlen(name);
  151.     for (i = 0; i <= 999; i++)
  152.     {
  153.         sprintf(p, ".%03d", i);
  154.         if (_dos_findfirst(name, 0x17, &srchbuf))
  155.             return 1;
  156.     }
  157.     return 0;
  158. }
  159.  
  160. static    void    print_ing( CONST char *name )
  161. {
  162.     LHX_fprintf( stderr, "\r%-12s - Printing\n\n", name );
  163. }
  164. static    char    _TESTING_[] = "Testing ";
  165. static    char    _MELTING_[] = "Melting ";
  166.  
  167. void        extract(char *bdir)
  168. {
  169.     char       *path;
  170.     int         method, handle;
  171.  
  172.     memcpy(methods[9], hpb.method, 5);
  173.     for (method = 0; memcmp(hpb.method, methods[method], 5); method++)
  174.         ;
  175.     if (method == 9)
  176.     {
  177.         skipdisp(METHODERR);
  178.         return;
  179.     }
  180.  
  181.     switch (cmd)
  182.     {
  183.         case 'E':
  184.             form_path(hpb.pathname);
  185.             hpb.filename = getfilename(hpb.pathname);
  186.             path = (flg_x) ? hpb.pathname : hpb.filename;
  187.             strcpy(filename3, bdir);
  188.             if (*(unsigned char *) path == DELIM)
  189.             {
  190.                 if (filename3[1] == ':')
  191.                 {
  192.                     filename3[2] = '\0';
  193.                 } else
  194.                 {
  195.                     *filename3 = '\0';
  196.                 }
  197.             }
  198.             strcat(filename3, path);
  199.             {
  200.                 int         ret;
  201.                 ret = tstdir(filename3);
  202.                 switch (ret)
  203.                 {
  204.                     case 'R':
  205.                         if (rename_ext(filename3))
  206.                             break;
  207.                         skipdisp(NOMOREEXT);
  208.                     case 'S':
  209.                         return;
  210.                 }
  211.             }
  212.             {
  213.                 long        dskfree;
  214.                 dskfree = diskspace(filename3);
  215.                 if (dskfree < hpb.original)
  216.                 {
  217.                     skipdisp(DISKFULL);
  218.                     return;
  219.                 }
  220.             }
  221.  
  222.             file3 = mywopen(filename3);
  223.             LHX_fprintf(stderr, "Melting ");
  224.             LHX_printf("%-12s ", getfilename(path));
  225.             break;
  226.  
  227.         case 'P':
  228. #ifndef CAN_NOT_USE_FDOPEN
  229.             handle = fileno(stdout);
  230.             flg_n |= isatty(handle);
  231.             if (flg_n == 0)
  232.                 LHX_fprintf(stderr, "Melting ");
  233.             file3 = fdopen(dup(handle), "wb");
  234.             LHX_fprintf(file3, "\r\n<< %s >>\r\n\r\n", hpb.filename);
  235. #else
  236.             file3 = stdout;
  237. #endif
  238.             break;
  239.  
  240.         case 'T':
  241.             if (hpb.level < 0)
  242.             {
  243.                 skipdisp(NOCRC);
  244.                 return;
  245.             }
  246.             file3 = NULL;
  247.             break;
  248.     }
  249.  
  250.     interface.method   = method;
  251.     interface.dicbit   = 13;        /* method + 8; */
  252.     interface.infile   = file1;
  253.     interface.outfile  = file3;
  254.     interface.original = hpb.original;
  255.     interface.packed   = hpb.packed;
  256.     interface.dispflg  = flg_n;
  257.  
  258.     switch (method)
  259.     {
  260.         case 0:
  261.         case 8:
  262.             if ( cmd == 'P' )
  263.             {    print_ing( hpb.filename );
  264.             } else
  265.             {    start_indicator(hpb.filename, interface.original
  266.                                 ,verify_mode ? _TESTING_ : _MELTING_, 2048);
  267.             }
  268.             copyfile(file1, file3, hpb.original, 1);
  269.             break;
  270.         case 6:
  271.             interface.dicbit = 11;
  272.             if ( cmd == 'P' )
  273.             {    print_ing( hpb.filename );
  274.             } else
  275.             {    start_indicator(hpb.filename, interface.original
  276.                                 ,verify_mode ? _TESTING_ : _MELTING_
  277.                                 ,1 << interface.dicbit);
  278.             }
  279.             decode(&interface);
  280.             break;
  281.         case 1:
  282.         case 4:
  283.         case 7:
  284.             interface.dicbit = 12;
  285.         default:
  286.             if ( cmd == 'P' )
  287.             {    print_ing( hpb.filename );
  288.             } else
  289.             {    start_indicator(hpb.filename, interface.original
  290.                                 ,verify_mode ? _TESTING_ : _MELTING_
  291.                                 ,1 << interface.dicbit);
  292.             }
  293.             decode(&interface);
  294.     }
  295.     if ( (file3 != stdout && file3 != stderr) && file3 )
  296.     {
  297.         fflush(file3);
  298.         setfiletime(file3, hpb.utc);
  299.         fclose(file3);
  300.         file3 = NULL;
  301.     }
  302.     if (hpb.level >= 0 && crc != hpb.filecrc)
  303.     {
  304.         errorlevel = 1;
  305.         LHX_fprintf(stderr, "\rCRC err\n");
  306.         if (cmd == 'E')
  307.         {
  308.             if (flg_m == 0)
  309.             {
  310.                 LHX_fprintf(stderr, " delete(y/n)? ");
  311.                 if (getyn() == 'Y')
  312.                     FS_remove(filename3);
  313.             } else
  314.             {
  315.                 FS_remove(filename3);
  316.             }
  317.         }
  318.         if (flg_m == 0)
  319.         {
  320.             LHX_fprintf(stderr, " continue(y/n)? ");
  321.             if (getyn() != 'Y')
  322.                 error(CTRLBRK, NULL);
  323.         }
  324.     } else
  325.     {
  326.         if ( cmd == 'P' )
  327.             LHX_putc('\n');
  328.         else
  329.             finish_indicator( hpb.filename, verify_mode ? "Tested  " : "Melted  ");
  330.         if (cmd == 'E' && flg_a)
  331.             _dos_setfileattr(filename3, hpb.attr);
  332.     }
  333. }
  334.  
  335. void        dispusage(void)
  336. {
  337.     LHX_puts(use);    /* stdout    */
  338.     MAIN_EXIT(2);
  339. }
  340.